#include "../include/Sessionmanager.h"
#include "../include/Session.h"

namespace Reactor
{
	SessionManager::~SessionManager()
	{

	}

	void SessionManager::addSession(const std::shared_ptr<Session>& _session)
	{
		if (_session == nullptr)
		{
			return;
		}
		SessionId _id = _session->sessionId();
		HashSegmentIndex _index = Poco::hash(_id) % SEGMENTS;
		HashSegmentPtr _segment = d->_sessionTables[_index];
		Poco::ScopedWriteRWLock lock(_segment->_lock);
		auto it = _segment->_sessionTable.find(_id);
		if (it == _segment->_sessionTable.end())
		{
			_segment->_sessionTable.insert(std::make_pair(_id, _session));
		}
	}

	void SessionManager::removeSession(const std::string& _sessionId)
	{
		if (_sessionId.empty())
		{
			return;
		}
		SessionId _id = _sessionId;
		HashSegmentIndex _index = Poco::hash(_id) % SEGMENTS;
		HashSegmentPtr _segment = d->_sessionTables[_index];
		Poco::ScopedWriteRWLock lock(_segment->_lock);
		auto it = _segment->_sessionTable.find(_id);
		if (it != _segment->_sessionTable.end())
		{
			_segment->_sessionTable.erase(it);
		}
	}

	std::shared_ptr<Session> SessionManager::session(const std::string& _id)
	{
		if (_id.empty())
		{
			return nullptr;
		}

		HashSegmentIndex _index = Poco::hash(_id) % SEGMENTS;
		HashSegmentPtr _segment = d->_sessionTables[_index];
		Poco::ScopedReadRWLock lock(_segment->_lock);
		auto it = _segment->_sessionTable.find(_id);
		if (it != _segment->_sessionTable.end())
		{
			return it->second;
		}
		return nullptr;
	}

	HashSegmentVector& SessionManager::RefHashSegmentVector()
	{
		return d->_sessionTables;
	}

	SessionManager::SessionManager()
	{
		d.reset(new SessionManagerPrivate);
		initialize();
	}

	void SessionManager::initialize()
	{
		for (int i = 0; i < SEGMENTS; ++i)
		{
			HashSegmentPtr _segment(new HashSegment);
			d->_sessionTables[i] = _segment;
		}
	}

	void SessionManager::destroy()
	{

	}
}